package com.zfp.core.dao;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.apache.ibatis.session.RowBounds;
import org.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;

import com.zfp.core.plugins.page.Page;
import com.zfp.core.utils.ReflectHelper;
import com.zfp.core.utils.ReflectionFatherUtils;


/**
 * 
 * <p>ClassName:BaseDao</p>
 * <p>Description:所有DAO的基类</p>
 * @author wangxiaobo
 * @date 2015-10-14
 */
@Repository("baseDAO")
public abstract class BaseDao<T extends Serializable> {
	@Resource(name = "sqlSessionTemplate")
	protected SqlSessionTemplate sqlSessionTemplate;
	private static Logger logger = Logger.getLogger(BaseDao.class);

	/**
	 * 修改
	 * @param record
	 * @return
	 */
	public int update(Object record) {
		return sqlSessionTemplate.update(record.getClass().getSimpleName() + ".update", record);
	}


	/**
	 * 修改
	 * @param statementName
	 * @return
	 */
	public int update(String statementName) {
		int rows = sqlSessionTemplate.update(statementName);
		return rows;
	}

	/**
	 * 修改
	 * @param statementName
	 * @param record
	 * @return
	 */
	public int update(String statementName, Object record) {
		int rows = sqlSessionTemplate.update(statementName, record);
		return rows;
	}

	/**
	 * 插入
	 * @param entity
	 * @return
	 */
	public int insert(Object entity) {
		int count = sqlSessionTemplate.insert(entity.getClass().getSimpleName() + ".insert", entity);
		return count;
	}

	/**
	 * 插入
	 * @param statementName
	 * @param entity
	 * @return
	 */
	public int insert(String statementName, Object entity) {
		int count = sqlSessionTemplate.insert(statementName, entity);
		return count;
	}


	/**
	 * 通过主键删除对象
	 * @param statementName
	 * @param id
	 * @return
	 */
	public int deleteById(String statementName, Long id) {
		return sqlSessionTemplate.delete(statementName, id);
	}

	/**
	 * 删除
	 * @param <T>
	 * @param entity
	 * @return
	 */
	@SuppressWarnings("hiding")
	public <T> int delete(Object entity) {
		int rows = sqlSessionTemplate.delete(entity.getClass().getSimpleName() + ".delete", entity);
		return rows;
	}

	/**
	 * 删除
	 * @param statementName
	 * @return
	 */
	public int delete(String statementName) {
		int rows = sqlSessionTemplate.delete(statementName);
		return rows;
	}

	/**
	 * 删除
	 * @param statementName
	 * @param record
	 * @return
	 */
	public int delete(String statementName, Object record) {
		int rows = sqlSessionTemplate.delete(statementName, record);
		return rows;
	}

	
	/**
	 * 通过主键获取单个对象
	 * @param <T>
	 * @param statementName
	 * @param id
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "hiding" })
	public <T> T getById(String statementName, String id) {
		return (T) sqlSessionTemplate.selectOne(statementName, id);
	}
	
	/**
	 * 通过主键获取单个对象
	 * @param <T>
	 * @param record
	 * @param id
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "hiding" })
	public <T> T getById(Object record, String id) {
		return (T) sqlSessionTemplate.selectOne(record.getClass().getSimpleName() + ".getById", id);
	}

	/**
	 * 查询
	 * @param statementName
	 * @return
	 */
	public Object getObject(String statementName) {
		return sqlSessionTemplate.selectOne(statementName);
	}

	/**
	 * 查询
	 * @param statementName
	 * @param object
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "hiding" })
	public <T> T  getObject(String statementName, Object object) {
		return (T)sqlSessionTemplate.selectOne(statementName, object);
	}

	/**
	 * 查询
	 * @param statementName
	 * @param object
	 * @return
	 */
	@SuppressWarnings("hiding")
	public <T> T getSingleObject(String statementName, Object object) {
		List<T> list = sqlSessionTemplate.selectList(statementName, object);
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}


	/**
	 * 查询
	 * @param statementName
	 * @param object
	 * @return
	 */
	public List<T> list(String statementName, Object object) {
		return sqlSessionTemplate.selectList(statementName, object);
	}
	
	/**
	 * 查询
	 * @param object
	 * @return
	 */

	public List<T> list(Object object) {
		return sqlSessionTemplate.selectList(object.getClass().getSimpleName() + ".findAll", object);
	}

	/**
	 * 分页查询
	 * @param statementName
	 * @param page
	 * @return
	 */
	public  Page<T> selectPage(String statementName, Page<T> page) {
		return _queryForPage(statementName, page, null);
	}
	
	/**
	 * 分页查询
	 * @param page
	 * @param entity
	 * @return
	 */
	public  Page<T> pageList(Page<T> page, T entity) {
		return _queryForPage(entity.getClass().getSimpleName() + ".findAll", page, entity);
	}
	
	/**
	 * 分页查询
	 * @param statementName
	 * @param page
	 * @param entity
	 * @return
	 */
	public Page<T> pageList(String statementName, Page<T> page, T entity) {
		return _queryForPage(statementName, page, entity);
	}
	
	/**
	 * 计算Mybatis查询语句的记录总数
	 * @param statementName
	 * @param parameterObject
	 * @return
	 * @throws DataAccessException
	 */
	@SuppressWarnings("unchecked")
	public int queryForCount(final String statementName, final Object parameterObject) throws DataAccessException {
		List list = sqlSessionTemplate.selectList(statementName, parameterObject);
		int count = null != list && !list.isEmpty() ? list.size() : 0;
		return count;
	}
	
	/**
	 * 分页查询
	 * @param statementName
	 * @param page
	 * @param parameterObject
	 * @return
	 * @throws DataAccessException
	 */
	@SuppressWarnings("unchecked")
	private Page<T> _queryForPage(String statementName, Page<T> page,
			Object parameterObject) throws DataAccessException {
		if (page == null) {
			page = new Page<T>();
		}
		
		int totalSize = page.getTotalResult();
		
		//取到总数
		ReflectionFatherUtils.setFieldValue(parameterObject, "pageSign","pageSign");
		sqlSessionTemplate.selectOne(statementName, parameterObject);
		String pageSignTemp = (String) ReflectionFatherUtils.getFieldValue(parameterObject, "pageSign");
		if (pageSignTemp != null && !"".equals(pageSignTemp)) {
			totalSize = Integer.parseInt(pageSignTemp);
		}
		ReflectionFatherUtils.setFieldValue(parameterObject, "pageSign", "");
		
		page.setTotalResult(totalSize);
		if (page.getCurrentPage() > page.getTotalPage()) {
			if (page.getTotalPage() <= 0) {
				page.setCurrentPage(1);
			} else {
				page.setCurrentPage(page.getTotalPage());
			}
		}

		int curPageIndex = page.getCurrentPage();
		int pageSize = page.getShowCount();
		int startNum = (curPageIndex - 1) * pageSize;
		RowBounds rowBounds = new RowBounds(startNum, pageSize);
		List pagels = sqlSessionTemplate.selectList(statementName,parameterObject, rowBounds);
		page.setResult(pagels);
		return page;
	}
	
	/**
	 * 查询已list对象返回
	 * @param entity
	 * @return
	 */
	public  List<T> findAllList(T entity) {
		return sqlSessionTemplate.selectList(entity.getClass().getSimpleName() + ".findAll", entity);
	}
	
	
	/**
	 * 
	 * 功能：批量删除对象<br>
	 * @param subListForDel
	 * @param statementName
	 */
	@SuppressWarnings("unchecked")
	public void batchDelete(final List subListForDel, final String statementName) throws Exception {
		try {
			sqlSessionTemplate.delete(statementName, subListForDel);
		} catch (Exception e) {
			logger.error(e);
			throw e;// 必须抛异常才能回滚。
		}
	}

}